/*
 * Graph.cpp
 *
 *  Created on: 30.03.2014
 *      Author: Medvedeva Anna
 */

#include <list>
#include <stack>
#include <deque>
#include <vector>
#include <iostream>
#include "Graph.h"
#include <fstream>

using namespace std ;


void Graph::make_black(vector <int > &colors, int vertex)
{
	colors[vertex] = 2;
}

void Graph::make_grey(vector <int > &colors, int vertex)
{
	colors[vertex] = 1;
}

void Graph::make_compact_digraph(ifstream &in)
{
	in >> this-> numbVertices >> this-> numbEdges >> flagOrient;
	cout << "numbVertices "<< this-> numbVertices << " numbEdges " << numbEdges << " flagOrient " << flagOrient << endl;
	if (numbVertices + 4*numbEdges < numbVertices*numbVertices) {
		//cout << "make_list_edges();"<< endl;
		make_list_edges(in);
	} else {
		//cout << "make_connect_matrix()" << endl;
		make_connect_matrix(in);
	}
}

void Graph::make_connect_matrix(ifstream &in)
{
	vector <int> Edg(numbVertices,0);
	for (int i = 0; i < numbVertices;i++){
		connect_matrix.push_back(Edg);
	}
	if (!flagOrient){
		for (int i = 0; i < numbEdges; i++){
			int vert1, vert2;
			in >> vert1 >> vert2;
			vert1--; vert2--;
			connect_matrix[vert1][vert2] = 1;
			connect_matrix[vert2][vert1] = 1;
		}
	} else {
		for (int i = 0; i < numbEdges; i++){
			int vert1, vert2;
			in >> vert1 >> vert2;
			cout << "vert 1 vert 2 "<< vert1 << vert2<< endl;
			vert1--; vert2--;
			connect_matrix[vert1][vert2] = 1;
		}
	}
}

void Graph::make_list_edges(ifstream &in)
{
	list <int> Edg;
	for (int i = 0; i < numbVertices;i++){
		list_edges.push_back(Edg);
	}
	if (!flagOrient) {
		for (int i = 0; i < numbEdges; i++) {
			int vert1, vert2;
			in >> vert1 >> vert2;
			vert1--; vert2--;
			list_edges[vert1].push_back(vert2);
			list_edges[vert2].push_back(vert1);
		}
	} else {
		for (int i = 0; i < numbEdges; i++) {
			int vert1, vert2;
			in >> vert1 >> vert2;
			vert1--; vert2--;
			//cout << "vert1--; vert2--" << vert1 << " " << vert2<< endl;
			list_edges[vert1].push_back(vert2);
		}
	}
}

void Graph::print_graph()
{
	if (!list_edges.empty()) {
		print_list_edges();
	} else {
		print_connect_matrix();
	}
	return ;
}

void Graph::print_list_edges()
{
	for (int i = 0;i < numbVertices; i++) {
		cout << "Список вершины " << (i+1) << ": ";
		for(list<int>::iterator j = list_edges[i].begin(); j != list_edges[i].end(); j++) {
			cout << *j + 1 << " ";
		}
		cout << endl;
	}

}

void Graph::print_connect_matrix()
{
	for (int i = 0;i < numbVertices; i++ ) {
		for (int j = 0;j < numbVertices; j++ ) {
			cout << connect_matrix[i][j]<< " ";
		}
		cout << endl;
 	}
}

void Graph::make_list_edges()
{
	list <int> Edg;
	for (int i = 0; i < numbVertices;i++){
		list_edges.push_back(Edg);
	}
	if (!flagOrient) {
		for (int i = 0; i < numbEdges; i++) {
			int vert1, vert2;
			cin >> vert1 >> vert2;
			vert1--; vert2--;
			list_edges[vert1].push_back(vert2);
			list_edges[vert2].push_back(vert1);
		}
	} else {
		for (int i = 0; i < numbEdges; i++) {
			int vert1, vert2;
			cin >> vert1 >> vert2;
			vert1--; vert2--;
			//cout << "vert1--; vert2--" << vert1 << " " << vert2<< endl;
			list_edges[vert1].push_back(vert2);
		}
	}
}

void Graph::make_connect_matrix()
{
	vector <int> Edg(numbVertices,0);
	for (int i = 0; i < numbVertices;i++){
		connect_matrix.push_back(Edg);
	}
	if (!flagOrient){
		for (int i = 0; i < numbEdges; i++){
			int vert1, vert2;
			cin >> vert1 >> vert2;
			vert1--; vert2--;
			connect_matrix[vert1][vert2] = 1;
			connect_matrix[vert2][vert1] = 1;
		}
	} else {
		for (int i = 0; i < numbEdges; i++){
			int vert1, vert2;
			cin >> vert1 >> vert2;
			vert1--; vert2--;
			connect_matrix[vert1][vert2] = 1;
		}
	}
}

void Graph::make_compact_digraph()
{
	cin >> this-> numbVertices >> this-> numbEdges >> flagOrient;
	cout << "numbVertices "<< this-> numbVertices << " numbEdges " << numbEdges << " flagOrient " << flagOrient << endl;
	//cout << "Im here 1\n";
	if (numbVertices + 4*numbEdges < numbVertices*numbVertices) {
		cout << "make_list_edges();"<< endl;
		make_list_edges();
	}
	else {
		cout << "make_connect_matrix()" << endl;
		make_connect_matrix();
	}
	//cout << "Im here 2\n";
}

